﻿using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

namespace FileUtility
{
    public static class ExtString
    {
        public static int GetLength(this string s)
        {
            return s.Length;
        }
        public static string[] Split(this string strLine, int[] unitLengthArr,int[] ignoreZeroPosition)
        {
            string[] strArr = new string[unitLengthArr.Length];
            int currentPosition = 0;
            int i = 0;
            int length = unitLengthArr.Sum();
             
            unitLengthArr.ToList().ForEach(len =>
            {
                if (currentPosition + len <= strLine.Length)
                {
                    string str = strLine.Substring(currentPosition, len);
                    if (ignoreZeroPosition != null && (!ignoreZeroPosition.Contains(i)))
                    {
                        strArr[i] = str.TrimStart("0".ToCharArray());
                    }
                    else
                    {
                        strArr[i] = str;
                    }
                }
                else
                {

                }
                currentPosition = currentPosition + len;
                i++;
            });
            return strArr;
        }
    }

    public class FileUtility
    {
        public static DataTable ReadFileContentToDataTable(string filePath, DataTable dtTarget, Guid batchId, string charSplit)
        {
            string exMsg = "";
            try
            {
                dtTarget.Rows.Clear();
                string[] _strArrContents = System.IO.File.ReadAllLines(filePath, Encoding.GetEncoding("gb2312"));
                if (batchId != null)
                {
                    int count = 0;
                    char[] splitArr = ConvertToCharArray(charSplit);
                    foreach (string strLine in _strArrContents)
                    {
                        count++;
                        try
                        {
                            string _strLine = batchId.ToString() + splitArr[0].ToString() + strLine;
                            //string[] _strArrLine = _strLine.Split(charSplit.ToCharArray());
                            string[] _strArrLine = _strLine.Split(splitArr,StringSplitOptions.None);
                            DataRow dr = dtTarget.NewRow();
                            dr.ItemArray = _strArrLine;
                            dtTarget.Rows.Add(dr);
                        }
                        catch (Exception ex)
                        {
                            exMsg = exMsg + "Row:" + count + "," + strLine + "," + ex.Message + "\n";
                            break;
                        }
                    }
                }
                else
                {

                    foreach (string strLine in _strArrContents)
                    {
                        string[] _strArrLine = strLine.Split(charSplit.ToCharArray());
                        DataRow dr = dtTarget.NewRow();
                        if (_strArrLine.Length > dr.ItemArray.Length)
                        {
                            dr.ItemArray = _strArrLine;
                            dtTarget.Rows.Add(dr);
                        }
                    }
                }
                if (!string.IsNullOrEmpty(exMsg))
                {
                    dtTarget.Rows.Clear();
                    throw new Exception(exMsg);
                }
                return dtTarget;
            }
            catch (Exception ex)
            {
                throw new Exception(exMsg);
                
            }

        }

        public static DataTable ReadFileContentToDataTable(string filePath, DataTable dtTarget, Guid batchId, string charSplit, long startPosition, int rowsCount, out long endPosition)
        {
            dtTarget.Rows.Clear();
            System.IO.FileStream _fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            System.IO.StreamReader _sr = new System.IO.StreamReader(_fs);
            endPosition = startPosition;
            _fs.Seek(startPosition, SeekOrigin.Current);
            if (batchId != null)
            {
                for (int i = 0; i < rowsCount; i++)
                {
                    string _line = _sr.ReadLine();
                    endPosition = endPosition + _line.Length + 1;
                    DataRow dr = dtTarget.NewRow();
                    _line = batchId.ToString() + charSplit + _line;
                    dr.ItemArray = _line.Split(charSplit.ToCharArray());
                }
            }
            else
            {
                for (int i = 0; i < rowsCount; i++)
                {
                    string _line = _sr.ReadLine();
                    endPosition = endPosition + _line.Length + 1;
                    DataRow dr = dtTarget.NewRow();
                    dr.ItemArray = _line.Split(charSplit.ToCharArray());
                }
            }
            _fs.Close();
            return dtTarget;
        }

        public static DataTable ReadFileContentToDataTable(string filePath, DataTable dtTarget, Guid batchId, int[] columnLengthArr)
        {
            string exMsg = "";
            try
            {
                dtTarget.Rows.Clear();
                string[] _strArrContents = System.IO.File.ReadAllLines(filePath, Encoding.GetEncoding("gb2312"));
                if (batchId != null)
                {
                    int count = 0;
                    if (columnLengthArr[0] != 36)
                    {
                        exMsg = "Please set batchId length is 36 at position 0";
                    }

                    foreach (string strLine in _strArrContents)
                    {
                        count++;
                        string _strLine = batchId.ToString() + strLine;
                        try
                        {
                            //Split char ,and ignore the first '0'
                            string[] _strArrLine = _strLine.Split(columnLengthArr,new int[1]{0});
                            DataRow dr = dtTarget.NewRow();
                            dr.ItemArray = _strArrLine;
                            dtTarget.Rows.Add(dr);
                        }
                        catch (Exception ex)
                        {
                            exMsg = exMsg + "Row:" + count + "," + _strLine + "," + ex.Message + "\n";
                            break;
                        }
                    }

                }
                else
                {

                    foreach (string strLine in _strArrContents)
                    {
                        string[] _strArrLine = strLine.Split(columnLengthArr,null);
                        DataRow dr = dtTarget.NewRow();
                        if (_strArrLine.Length > dr.ItemArray.Length)
                        {
                            dr.ItemArray = _strArrLine;
                            dtTarget.Rows.Add(dr);
                        }
                    }
                }
                if (!string.IsNullOrEmpty(exMsg))
                {
                    dtTarget.Rows.Clear();
                    throw new ExceptionExt.FileContentRedaerException(exMsg);
                }
                return dtTarget;
            }
            catch (Exception ex)
            {
                throw new ExceptionExt.FileContentRedaerException(ex.Message, ex);
            }

        }

        private static char[] ConvertToCharArray(string str)
        {
            char[] arr;
            switch (str)
            {
                case "TAB":
                    arr = new char[] { '\t' };
                    break;
                case "LINE":
                    arr = new char[] { '\n' };
                    break;
                case "RET":
                    arr = new char[] { '\r' };
                    break;
                default :
                    char c='^';
                    char.TryParse(str, out c);
                    if(char.Equals(c,'\0'))
                    {
                        c='^';
                    }
                    arr = new char[] { c };
                    break;
            }
            return arr;
        }

    
    }
}
